{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ac1b2f80",
   "metadata": {},
   "source": [
    "| [03_data_science/09_Scikit-Learn分类.ipynb](https://github.com/shibing624/python-tutorial/blob/master/03_data_science/09_Scikit-Learn分类.ipynb)  | Scikit-Learn数据分类  |[Open In Colab](https://colab.research.google.com/github/shibing624/python-tutorial/blob/master/03_data_science/09_Scikit-Learn分类.ipynb) |\n",
    "\n",
    "# Scikit-Learn的应用\n",
    "机器学习库，机器学习分为监督学习和非监督学习：\n",
    "![ml](../docs/imgs/ml_taxonomy.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "334a67eb",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 分类\n",
    "先学习下监督学习中的分类任务：\n",
    "\n",
    "\n",
    "加载数据集："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2d6591a6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'images', 'DESCR'])"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import datasets\n",
    "digits = datasets.load_digits()\n",
    "\n",
    "digits.keys()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "993cbecf",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.,  0.,  5., ...,  0.,  0.,  0.],\n",
       "       [ 0.,  0.,  0., ..., 10.,  0.,  0.],\n",
       "       [ 0.,  0.,  0., ..., 16.,  9.,  0.],\n",
       "       ...,\n",
       "       [ 0.,  0.,  1., ...,  6.,  0.,  0.],\n",
       "       [ 0.,  0.,  2., ..., 12.,  0.,  0.],\n",
       "       [ 0.,  0., 10., ..., 12.,  1.,  0.]])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "digits.data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "51b8beea",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0 1 2 ... 8 9 8]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([[ 0.,  0.,  5., 13.,  9.,  1.,  0.,  0.],\n",
       "       [ 0.,  0., 13., 15., 10., 15.,  5.,  0.],\n",
       "       [ 0.,  3., 15.,  2.,  0., 11.,  8.,  0.],\n",
       "       [ 0.,  4., 12.,  0.,  0.,  8.,  8.,  0.],\n",
       "       [ 0.,  5.,  8.,  0.,  0.,  9.,  8.,  0.],\n",
       "       [ 0.,  4., 11.,  0.,  1., 12.,  7.,  0.],\n",
       "       [ 0.,  2., 14.,  5., 10., 12.,  0.,  0.],\n",
       "       [ 0.,  0.,  6., 13., 10.,  0.,  0.,  0.]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(digits.target)\n",
    "digits.images[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b9e2d999",
   "metadata": {},
   "source": [
    "显示图片："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "166b9418",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWoAAADQCAYAAAAu/itEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAQ90lEQVR4nO3dX4iV5drH8d/1uilNptRmtpTWnpTQIom2k5DCzo3s/mCgFqbRQToHRhZFdlAHeVIGO0jBYDwQGSvQkg5GA/9kSfSCGs1M9GJtk3QYcTSa8V+UJGnc+0DFadbc97PmmfWsuab3+4FNjtdac19z7TW/puXl81gIQQAAv/5nqBsAAKQR1ADgHEENAM4R1ADgHEENAM4R1ADg3F/KeZCZPSRpraQRkjaEEP6denxtbW2or68fcDPnzp1L1js7O6O1MWPGRGs333xztGZmWW1Fezl58mTZT847kyxHjhyJ1i5cuBCt3XrrrdHaddddl7uf9vb2kyGEunIeW9RMzp8/H61999130VpNTU20Nnny5Nz9VGMmp06dStZT3zsjR46M1u68885oLe/3jjSwmUjFvVZS68lHjx6N1oroJZUpmUFtZiMkNUn6l6QuSa1m9lEI4T+x59TX16utrW3Aje7fvz9Zb2xsjNYeffTRaG3lypXRWupFmtLQ0DCgx+edSZYFCxZEa93d3dHa2rVro7WBfm29mVn81d1HUTM5dOhQtHbfffdFa/fff3+01tLSkrufaszk3XffTdaXLFmSPDNm79690Vre7x1pYDORinutpP6lvnz58mitubm54r2kvu/KeetjhqTDIYSOEMJvkj6QNK9CvQEAMpQT1BMkHev1cdfl3wMAVEE5Qd3feyYlb+yY2TIzazOztp6ensF39ifATEoxk1LMpH/M5apygrpL0i29Pp4o6UTfB4UQ1ocQGkIIDXV1Zf8ZwZ8aMynFTEoxk/4xl6vKCepWSbeb2W1mdo2kxZI+KrYtAMAVmVsfIYSLZvacpI91aT2vOYTwbRHNpLY6pPRq1enTp6O1UaNGRWv79u1LnpnaEvBg7Nix0drWrVujtV27dkVrg9n6qIbjx48n61OnTo3WUvM6cOBA7p6qYfXq1dHahg0bks/dvn17tDZ37txoraOjI1pLre4NF9u2bYvWPH0flLVHHULYIWlHwb0AAPrB30wEAOcIagBwjqAGAOcIagBwjqAGAOfK2vqopGPHjkVrqfU7Kb2Cl1q7Sj3P+3pe1ipaagUvZai/rsFIrVRJ0syZM6O1J598Mlp79tlnc/dUDan11aze77nnnmgttc443FfwUhddkqS33347WnvttdeitbNnz+ZtKXmlzxh+ogYA5whqAHCOoAYA5whqAHCOoAYA5whqAHCOoAYA56q+R/3zzz9Ha7Nnz04+N7UrnTJjxoxcz6uWLVu2RGvPPPNM8rlnzpzJdeb06dNzPc+DrMvhTpkyJVpbuHBhtLZ06dLcPVVD6vWf9TpI/R2Fxx9/PFpL7SEP5ua21ZK1c3/w4MFobc6cOdHaqlWrorVx48Ylz0zdNDeGn6gBwDmCGgCcI6gBwDmCGgCcI6gBwDmCGgCcq/p63k8//RStPfLII4WcmbrMadYqTTUsWrQoWps3b17yuak7rKecO3cuWstzGcZKS62FNTc3J5+7adOmXGeuW7cu1/M8yFpd/fXXX6O1hx9+OFdt586dyTOrtb7X1tYWrS1evDj53BUrVuQ6c+XKldHap59+mutzpvATNQA4R1ADgHMENQA4R1ADgHMENQA4R1ADgHNlreeZWaeknyX9LuliCKEh74E33HBDtPbll1/m/bTJda7UncaXLFmS+8zhLHU1tQkTJlSxk/699dZb0VpqNSpLa2trtDYcrgaXV+prS63Zvfjii9FaU1NT8syXXnopu7EKqKmpiday1hbXrFkTrX3xxRe5+pk1a1au56UMZI/6nyGEkxXvAACQxFsfAOBcuUEdJO02s3YzW1ZkQwCAPyo3qGeFEP4u6WFJz5rZP/o+wMyWmVmbmbX19PRUtMnhipmUYialmEn/mMtVZQV1COHE5X92S2qRVHJvqxDC+hBCQwihoa6urrJdDlPMpBQzKcVM+sdcrsoMajMbbWY1V34t6QFJ3xTdGADgknK2PsZLajGzK4/fHELYlffAm266KVrbs2dP8rn79++P1t57771c/Tz11FO5nodipW40m3XVttQ65r333pvrzKwbkjY05N5YrYjVq1cn66mr4KWuaPnhhx9Ga08//XR2Y1WQuplx6sqZknT8+PFobdq0adFa6qp7Rax5ZgZ1CKFD0t0VPxkAUBbW8wDAOYIaAJwjqAHAOYIaAJwjqAHAOYIaAJyr+l3IU5cdzNqFbmxsjNZmz54drX322WeZfXmVtZOZ2v3duHFjtLZjx45obc6cOdmNFSx1qdW9e/cmn5vajU1dIjU1r0mTJiXPHOo96tra2mT9sccey/V5U7vSb7zxRq7P6cno0aOjtTNnzkRry5ZV95JH/EQNAM4R1ADgHEENAM4R1ADgHEENAM4R1ADgnIUQKv9JzXokHb38Ya0kTzfFrVQ/fwshlH01c+czkYZgLn1mUskeKoWZlOL7p1ThMykkqP9wgFlbCGFol0x78dCPhx768tCThx5689CPhx5689CPhx56q0Y/vPUBAM4R1ADgXDWCen0VzhgID/146KEvDz156KE3D/146KE3D/146KG3wvsp/D1qAMDg8NYHADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADhHUAOAcwQ1ADj3l3IeZGYPSVoraYSkDSGEf6ceX1tbG+rr6wfczJEjR5L1a6+9NlqbOHHigM8bjM7OTp08edLKfXzemWRJzezChQvR2tSpUyveiyS1t7efDCHUlfPYvDM5c+ZMsn7x4sVo7dSpU9HauXPnorURI0Ykz7z77rujta+++qrwmfzwww/JeurrHj9+fKqfaM2s7Jd/iYG8Ti73kWsunZ2dyfrvv/8erU2ePHnA5w1GKlMyg9rMRkhqkvQvSV2SWs3soxDCf2LPqa+vV1tb24AbXbBgQbI+adKkaG316tUDPm8wGhoaBvT4vDPJkppZd3d3tLZ3796K9yJJZna03MfmncmWLVuS9VQobdq0KVrbt29ftHb99dcnz0zNc9SoUYXPZNWqVcn6O++8E62tWLEiWmtsbIzWRo4cmdlXzEBeJ1L+uaT6l9L/0m9paRnweYORypRy3vqYIelwCKEjhPCbpA8kzatQbwCADOUE9QRJx3p93HX59wAAVVBOUPf3nkkoeZDZMjNrM7O2np6ewXf2J8BMSjGTUsykf8zlqnKCukvSLb0+nijpRN8HhRDWhxAaQggNdXVl/xnBnxozKcVMSjGT/jGXq8oJ6lZJt5vZbWZ2jaTFkj4qti0AwBWZWx8hhItm9pykj3VpPa85hPBtEc0cOHAgWd+6dWu0tmbNmmgttWZz+PDhzL6GUtafdKdm0tTUVOFuhocbb7wxWmtubo7W3nzzzWgtayVwMBsQldDe3p77uanvnU8++SRaq/ZWRMzZs2ejtY0bN+b+vKn1w5kzZ0ZrRWxUlbVHHULYIWlHxU8HAGTibyYCgHMENQA4R1ADgHMENQA4R1ADgHNlbX1US+oqXlL6SnFjx46N1ubNi1+a5Pz588kzh3rt6oUXXsj93NTXPZwtWrQo93PXrVsXrR06dCha27NnT+4zq2H69OnJet4Lmo0bNy5aS81LkqZMmZKsV0rqqodZ5s+fH62lZrZt27bcZ+bBT9QA4BxBDQDOEdQA4BxBDQDOEdQA4BxBDQDOEdQA4JyrPeqsvcvUzUdTl6GcMWNGtDbUe9JZfvzxx2Q9dbnFCROG7x3TitppfvXVV3M9L+vSlXPmzMn1eStl6dKlyfrEiROjtY6OjmgttUed9fceqiV1Wdss77//frT2xBNPRGunT5/OfWYe/EQNAM4R1ADgHEENAM4R1ADgHEENAM4R1ADgnKv1vNQdoiXp5Zdfjta+/vrraG3x4sV5WxrUJTUrIWsNaNq0adHali1borUHH3wwWhszZkxmX0VLrX4N5s7sKfv374/WqnXJzrx++eWX3M9NzSu19urhdSKlV2xT66uSNGrUqGjt9ddfj9Y+//zzaC11V3Qp39z4iRoAnCOoAcA5ghoAnCOoAcA5ghoAnCOoAcC5stbzzKxT0s+Sfpd0MYTQUGRTMUWsSH3//fcV/5yVdMcddyTrqdWq7u7uaC21stjV1ZU8sxpX5UutMGWtcW7cuDFaa21tjda8r+AdP348Wps6dWryuU1NTdHakSNHorW5c+dGa9u3b0+e6WF9L+uqh6mZ5n2dr1ixIlnPev32ZyB71P8MIZwc8AkAgEHhrQ8AcK7coA6SdptZu5ktK7IhAMAflRvUs0IIf5f0sKRnzewffR9gZsvMrM3M2np6eira5HDFTEoxk1LMpH/M5aqygjqEcOLyP7sltUgqubdVCGF9CKEhhNBQV1dX2S6HKWZSipmUYib9Yy5XZQa1mY02s5orv5b0gKRvim4MAHBJOVsf4yW1mNmVx28OIewqopmsq6LV1NREa6+88kquMxcuXJjredXy/PPPJ+upG/6m1s0OHjwYrW3bti155vLly5P1oq1atSpZHzt2bLR21113VbqdqkndxDX1NUtSY2NjtHbq1KloLXVT3M2bNyfPHOrXSTlSK3ip19maNWuitdRVGPPKDOoQQoekuyt+MgCgLKznAYBzBDUAOEdQA4BzBDUAOEdQA4BzBDUAOOfqLuS7dqXXs1euXJnr86YuO+j90pbz5s1L1lN3Sk7tes6fPz/3mUNt586dyfru3bujtdQdq71L9Z76/1NK3207tYO9dOnSaC21m+1F1s59e3t7tJa6TPCBAweitSIuA8xP1ADgHEENAM4R1ADgHEENAM4R1ADgHEENAM5ZCKHyn9SsR9LRyx/WSvJ0U9xK9fO3EELZVzN3PhNpCObSZyaV7KFSmEkpvn9KFT6TQoL6DweYtYUQGgo9ZAA89OOhh7489OShh9489OOhh9489OOhh96q0Q9vfQCAcwQ1ADhXjaBeX4UzBsJDPx566MtDTx566M1DPx566M1DPx566K3wfgp/jxoAMDi89QEAzhUa1Gb2kJkdMrPDZpbvNuGV7afTzA6Y2ddmlr7leXE9MJPSHphJaQ+uZiIxl0g/1ZlJCKGQ/0kaIemIpEmSrpH0f5LuLOq8MnvqlFQ7hOczE2YyLGfCXIZ2JkX+RD1D0uEQQkcI4TdJH0jyfaHj4jGTUsykFDPp3//buRQZ1BMkHev1cdfl3xtKQdJuM2s3s2VDcD4zKcVMSnmcicRc+lOVmRR5hxfr5/eGesVkVgjhhJn9VdInZvZdCOF/q3g+MynFTEp5nInEXPpTlZkU+RN1l6Rben08UdKJAs/LFEI4cfmf3ZJadOk/paqJmZRiJqXczURiLv2p1kyKDOpWSbeb2W1mdo2kxZI+KvC8JDMbbWY1V34t6QFJ31S5DWZSipmUcjUTibn0p5ozKeytjxDCRTN7TtLHuvSntc0hhG+LOq8M4yW1mJl06eveHEJI3023wphJKWZSyuFMJObSn6rNhL+ZCADO8TcTAcA5ghoAnCOoAcA5ghoAnCOoAcA5ghoAnCOoAcA5ghoAnPsvVQFC32hdQlkAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 10 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "\n",
    "fig, ax = plt.subplots(\n",
    "    nrows=2,\n",
    "    ncols=5,\n",
    "    sharex=True,\n",
    "    sharey=True)\n",
    " \n",
    "ax = ax.flatten()\n",
    "for i in range(10):\n",
    "    ax[i].imshow(digits.data[i].reshape((8, 8)), cmap='Greys', interpolation='nearest')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b066a12f",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 模型训练和预测\n",
    "\n",
    "### SVM\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6eb48468",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(C=100, gamma=0.001)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import svm\n",
    "clf = svm.SVC(gamma = 0.001, C=100)\n",
    "\n",
    "clf.fit(digits.data[:-1], digits.target[:-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "a9c24f50",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 1])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.predict(digits.data[:2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1f661854",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import svm\n",
    "from sklearn import datasets\n",
    "clf = svm.SVC()\n",
    "iris = datasets.load_iris()\n",
    "X, y = iris.data, iris.target\n",
    "clf.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "64b93dfc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.predict(X[:150])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "44d02d30",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[:150]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b164a0fc",
   "metadata": {},
   "source": [
    "使用pickle序列化模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "79a06442",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
       "       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,\n",
       "       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n",
       "       2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pickle\n",
    "s = pickle.dumps(clf)\n",
    "clf2 = pickle.loads(s)\n",
    "predict_y = clf2.predict(X[:150])\n",
    "predict_y"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "622bc770",
   "metadata": {},
   "source": [
    "使用joblib保存："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "faa5409d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['clf.pkl']"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import joblib\n",
    "joblib.dump(clf, 'clf.pkl')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "8fcb0c01",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC()"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf = joblib.load('clf.pkl')\n",
    "clf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "82d945b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.remove('clf.pkl')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9fa5848d",
   "metadata": {},
   "source": [
    "### 随机映射 random projection\n",
    "sklearn.random_projection 模块实现了一种简单和计算高效的方法，通过交易控制量的精度（作为附加方差），以缩短数据的维数，从而缩短处理时间和缩小模型大小。 \n",
    "\n",
    "该模块实现两种类型的非结构化随机矩阵：高斯随机矩阵 GaussianRandomProjection 和稀疏随机矩阵 SparseRandomProjection。\n",
    "\n",
    "- 高斯随机矩阵：通过将原始输入空间投影在随机生成的矩阵上来降低维度。\n",
    "- 稀疏随机矩阵：相比于高斯随机映射，稀疏随机映射会更能保证降维的质量，并带来内存的使用效率和运算效率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "9957d465",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0.5488135 , 0.71518934, 0.60276335, ..., 0.4801078 , 0.64386404,\n",
       "        0.5017731 ],\n",
       "       [0.8115185 , 0.476084  , 0.523156  , ..., 0.83000296, 0.9328062 ,\n",
       "        0.30833843],\n",
       "       [0.29264206, 0.56651825, 0.13741443, ..., 0.6965229 , 0.4836966 ,\n",
       "        0.33955073],\n",
       "       ...,\n",
       "       [0.32059506, 0.24986687, 0.03107279, ..., 0.3893891 , 0.93272   ,\n",
       "        0.33276632],\n",
       "       [0.39553738, 0.8440175 , 0.15044175, ..., 0.53561085, 0.35458204,\n",
       "        0.935781  ],\n",
       "       [0.81402713, 0.85133713, 0.43113658, ..., 0.44645575, 0.3601266 ,\n",
       "        0.6258866 ]], dtype=float32)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn import random_projection\n",
    "rng = np.random.RandomState(0)\n",
    "X = rng.rand(10, 2000)\n",
    "X = np.array(X, dtype='float32')\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "8d5d064b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "float64\n"
     ]
    }
   ],
   "source": [
    "transformer = random_projection.GaussianRandomProjection()\n",
    "X_new = transformer.fit_transform(X)\n",
    "\n",
    "print(X_new.dtype)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40c96198",
   "metadata": {},
   "source": [
    "### LR\n",
    "使用逻辑回归（Logistic Regression, LR）模型：\n",
    "\n",
    "LR模型的详细介绍参考sklearn官方文档：[LR](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html#sklearn.linear_model.LogisticRegression\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "56e7e8e6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(fit_intercept=False)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import datasets\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "iris = datasets.load_iris()\n",
    "clf = LogisticRegression(solver='lbfgs', fit_intercept=False)\n",
    "clf.fit(iris.data, iris.target)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "158075b1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 0, 0]"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(clf.predict(iris.data[:3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a95d6706",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[:3]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8efe6b81",
   "metadata": {},
   "source": [
    "如果模型的label为文本："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "a5ea3e12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(fit_intercept=False)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.fit(iris.data, iris.target_names[iris.target])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "6fb57a6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['setosa', 'setosa', 'setosa']"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(clf.predict(iris.data[:3]))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "109dd48d",
   "metadata": {},
   "source": [
    "### set_params\n",
    "设置模型参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "355c9709",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "SVC(kernel='linear')"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from sklearn.svm import SVC\n",
    "\n",
    "rng = np.random.RandomState(0)\n",
    "X = rng.rand(100, 10)\n",
    "y = rng.binomial(1, 0.5, 100)\n",
    "X_test = rng.rand(5, 10)\n",
    "\n",
    "clf = SVC()\n",
    "clf.set_params(kernel='linear').fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3ef32801",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1, 0, 1, 1, 0])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "5b7b392e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 1, 0])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.set_params(kernel='rbf').fit(X, y)\n",
    "clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "baa791f5",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 多分类 vs. 多标签模型\n",
    "\n",
    "多分类模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "a14af6cd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OneVsRestClassifier(estimator=SVC(random_state=0))"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.svm import SVC\n",
    "from sklearn.multiclass import OneVsRestClassifier\n",
    "from sklearn.preprocessing import LabelBinarizer\n",
    "\n",
    "X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]\n",
    "y = [0, 0, 1, 1, 2]\n",
    "classify = OneVsRestClassifier(estimator=SVC(random_state=0))\n",
    "model = classify.fit(X, y)\n",
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f2697523",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 1, 1, 2])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "a6be23e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0],\n",
       "       [1, 0, 0],\n",
       "       [0, 1, 0],\n",
       "       [0, 1, 0],\n",
       "       [0, 0, 1]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = LabelBinarizer().fit_transform(y)\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "7f2a71ea",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 0, 0],\n",
       "       [1, 0, 0],\n",
       "       [0, 1, 0],\n",
       "       [0, 0, 0],\n",
       "       [0, 0, 0]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "classify.fit(X, y).predict(X) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "0f3dd271",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "classify.fit(X, y).score(X, y)\n",
    "# 0.6 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9ef62f68",
   "metadata": {},
   "source": [
    "多标签模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "d05df3d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import MultiLabelBinarizer\n",
    "y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "436a3bfa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 1, 0, 0, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [1, 0, 1, 1, 0],\n",
       "       [0, 0, 1, 0, 1]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y = MultiLabelBinarizer().fit_transform(y)\n",
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "02903a8d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OneVsRestClassifier(estimator=SVC(random_state=0))"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "classify = OneVsRestClassifier(estimator=SVC(random_state=0))\n",
    "model = classify.fit(X, y)\n",
    "model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "dc93e7a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 1, 0, 0, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [1, 0, 1, 0, 0]])"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.predict(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "eafbe52a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.score(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5b1f5c2",
   "metadata": {},
   "source": [
    "\n",
    "## 预测错误结果可视化\n",
    "\n",
    "\n",
    " `cross_val_predict` \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "c5cc3a05",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[6.3200e-03, 1.8000e+01, 2.3100e+00, 0.0000e+00, 5.3800e-01,\n",
       "        6.5750e+00, 6.5200e+01, 4.0900e+00, 1.0000e+00, 2.9600e+02,\n",
       "        1.5300e+01, 3.9690e+02, 4.9800e+00],\n",
       "       [2.7310e-02, 0.0000e+00, 7.0700e+00, 0.0000e+00, 4.6900e-01,\n",
       "        6.4210e+00, 7.8900e+01, 4.9671e+00, 2.0000e+00, 2.4200e+02,\n",
       "        1.7800e+01, 3.9690e+02, 9.1400e+00],\n",
       "       [2.7290e-02, 0.0000e+00, 7.0700e+00, 0.0000e+00, 4.6900e-01,\n",
       "        7.1850e+00, 6.1100e+01, 4.9671e+00, 2.0000e+00, 2.4200e+02,\n",
       "        1.7800e+01, 3.9283e+02, 4.0300e+00]])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn import datasets\n",
    "from sklearn.model_selection import cross_val_predict\n",
    "from sklearn.linear_model import LinearRegression\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "lr = LinearRegression()\n",
    "boston = datasets.load_boston()\n",
    "y = boston.target\n",
    "\n",
    "boston.data[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "83aebcd1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([30.04900564, 24.73268691, 30.36234996])"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predicted = cross_val_predict(lr, boston.data, y, cv=10)\n",
    "predicted[:3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "d0f2124a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots()\n",
    "ax.scatter(y, predicted)\n",
    "ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)\n",
    "ax.set_xlabel('Measured')\n",
    "ax.set_ylabel('Predicted')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "182b7c2d",
   "metadata": {},
   "source": [
    "本节完。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "552973a5",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}